package org.gthelper.security;



import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;


/**
 * Validation类
 * @author 
 *加解密和验证
 */
public class ValidationRSA implements IchkID
{
	//非对称加密密钥算法
	private static final String KEY_ALGORITHM = "RSA";
	//SHA加密算法的key
	private static final String KEY_SHA="SHA";
	//公钥
	private static final String PUBLIC_KEY = "publickeykey";
	//私钥
	private static final String PRIVATE_KEY = "privatekeykey";
	//密钥长度，必须为64的倍数,默认1024
	private static final int KEY_SIZE = 2048;
	//数字签名、验证算法
	private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
	
	
	


	
	

	/**
	 * 初始化密钥
	 * 
	 * @return Map	密钥Map
	 * @throws Exception
	 */
	public Map<String,Object> initKey()
			throws Exception
	{
		// 实例化密钥对生成器
		KeyPairGenerator keyPairGen = KeyPairGenerator
				.getInstance(KEY_ALGORITHM);

		// 初始化密钥对生成器
		keyPairGen.initialize(KEY_SIZE);

		// 生成密钥对
		KeyPair keyPair = keyPairGen.generateKeyPair();

		// 公钥
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

		// 私钥
		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

		// 封装密钥
		Map<String, Object> keyMap = new HashMap<String, Object>(2);

		keyMap.put(PUBLIC_KEY, publicKey);
		keyMap.put(PRIVATE_KEY, privateKey);

		return keyMap;
	}
	
	
	
	

	
	
	
	
	/**
	 * 取得公钥
	 * 
	 * @param keyMap	密钥Map
	 * @return byte[]	公钥
	 * @throws Exception
	 */
	public byte[] getPublicKey(Map<String, Object> keyMap)
			throws Exception {

		Key key = (Key) keyMap.get(PUBLIC_KEY);

		return key.getEncoded();
	}

	
	
	
	/**
	 * 取得私钥
	 * 
	 * @param keyMap
	 *            密钥Map
	 * @return byte[] 私钥
	 * @throws Exception
	 */
	public byte[] getPrivateKey(Map<String, Object> keyMap)
			throws Exception {

		Key key = (Key) keyMap.get(PRIVATE_KEY);

		return key.getEncoded();
	}
	

	

    
	
	/**
	 * 私钥解密
	 * @param data	待解密数据
	 * @param key	私钥
	 * @return byte[]	解密数据
	 * @throws Exception
	 */
	public byte[] decryptByPrivateKey(byte[] data, byte[] key)
			throws Exception {

		// 取得私钥
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);

		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

		// 生成私钥
		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

		// 对数据解密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

		cipher.init(Cipher.DECRYPT_MODE, privateKey);

		return cipher.doFinal(data);
	}
	

	
	
	
	/**
	 * 公钥解密
	 * 
	 * @param data	待解密数据
	 * @param key	公钥
	 * @return byte[] 解密数据
	 * @throws Exception
	 */
	public byte[] decryptByPublicKey(byte[] data, byte[] key)
			throws Exception {

		// 取得公钥
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);

		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

		// 生成公钥
		PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);

		// 对数据解密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

		cipher.init(Cipher.DECRYPT_MODE, publicKey);

		return cipher.doFinal(data);
	}
	
	
	
	
	
	
	
	  /**
		 * 校验
		 * 
		 * @param data	待校验数据
		 * @param publicKey	公钥
		 * @param sign	数字签名
		 * @return boolean 校验成功返回true 失败返回false
		 * @throws Exception
		 * 
		 */
		public boolean chkSign(byte[] data, byte[] sign, byte[] publicKey)
				throws Exception {

			// 转换公钥材料
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);

			// 实例化密钥工厂
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

			// 生成公钥
			PublicKey pubKey = keyFactory.generatePublic(keySpec);

			// 实例化Signature
			Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);

			// 初始化Signature
			signature.initVerify(pubKey);

			// 更新
			signature.update(data);

			// 验证
			return signature.verify(sign);
		}
	    
	
		
		
	/** 
     * SHA加密 
     *  
     * @param data 
     * @return 
     * @throws Exception 
     */  
    public byte[] encryptSHA(byte[] data) throws Exception {  
  
        MessageDigest sha = MessageDigest.getInstance(KEY_SHA);  
        sha.update(data);  
  
        return sha.digest();  
  
    }  
	
    /** 
	 * BASE64解密 
	 *  
	 * @param key 
	 * @return 
	 * @throws Exception 
	 */  
	public static byte[] decryptBASE64(String key) throws Exception {  
	    return (new BASE64Decoder()).decodeBuffer(key);  
	}  
	  
	/** 
	 * BASE64加密 
	 *  
	 * @param key 
	 * @return 
	 * @throws Exception 
	 */  
	public static String encryptBASE64(byte[] key) throws Exception {  
	    return (new BASE64Encoder()).encodeBuffer(key);  
	} 
    
    
}